﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using jmetal.core;
using jmetal.util;

namespace jmetal.operators.mutation
{
    public class BitFlipMutation : Mutation
    {

        public const double ETA_M_DEFAULT_ = 20.0;

        private static Type[] validTypes = new Type[] { System.Type.GetType("jmetal.encodings.solutionType.BinarySolutionType") };

        private double mutationProbability_ = 0.0;
        private double distributionIndex_ = ETA_M_DEFAULT_;

        public BitFlipMutation(Dictionary<string, object> parameters)
            : base(parameters)
        {
            System.Console.WriteLine("Creado un operador de mutation polinomial \n");

            Console.WriteLine("ValidTypes: " + validTypes[0]);
            if (parameters.ContainsKey("probability"))
                mutationProbability_ = (double)parameters["probability"];

            if (parameters.ContainsKey("distributionIndex"))
                distributionIndex_ = (double)parameters["distributionIndex"];

            Console.WriteLine("probability: " + mutationProbability_);
            Console.WriteLine("distributionIndex: " + distributionIndex_);
        }

        public override object execute(object obj)
        {

            Solution solution = (Solution)obj;

            Type type = Array.Find(validTypes, n => n == solution.type_.GetType());
            if (type == null)
                Console.WriteLine("PolynomialMutation. Type incompatible");
            else ;
            //Console.WriteLine ("PolynomialMutation. Type Compatible");

            doMutation(solution);

            return solution;
        }

        private void doMutation(Solution x)
        {
            double rnd, delta1, delta2, mut_pow, deltaq;
            double y, yl, yu, val, xy;
            double eta_m = distributionIndex_;

            for (int var = 0; var < x.numberOfVariables_; var++)
            {
                if (PseudoRandom.Instance().NextDouble() <= mutationProbability_)
                {
                    x.variable_[var].value_ = 1 - x.variable_[var].value_;
                }
            }
        }
    }
}
